Refactored some of the window hiding/showing code from WM_ACTIVATE to
authorCody Russell <bratsche@gnome.org>
Thu, 31 Jan 2008 22:40:37 +0000 (22:40 +0000)
committerCody Russell <bratsche@src.gnome.org>
Thu, 31 Jan 2008 22:40:37 +0000 (22:40 +0000)
2008-01-31  Cody Russell  <bratsche@gnome.org>

        * gdk/win32/gdkevents-win32.c:
        Refactored some of the window hiding/showing code from
        WM_ACTIVATE to WM_SIZE and WM_SYSCOMMAND.  Having this
        under WM_ACTIVATE was causing the application to go into
        a weird state when the user right-clicked on the taskbar
        entry of a window that was minimized.  (#505928)

svn path=/trunk/; revision=19451

ChangeLog
gdk/win32/gdkevents-win32.c

index 5d6d9de3d59411e0f774108c2a128d40d56d6d34..8c2c1989d9b7d03ee461f2f24bbd66d1a613c9c1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-01-31  Cody Russell  <bratsche@gnome.org>
+
+       * gdk/win32/gdkevents-win32.c:
+       Refactored some of the window hiding/showing code from
+       WM_ACTIVATE to WM_SIZE and WM_SYSCOMMAND.  Having this
+       under WM_ACTIVATE was causing the application to go into
+       a weird state when the user right-clicked on the taskbar
+       entry of a window that was minimized.  (#505928)
+       
 2008-01-31  Cody Russell  <bratsche@gnome.org>
 
        * gtk/gtkpaned.c (gtk_paned_set_position):
index a916228418a8f4780d1e86e7689fecaa0e82a238..584c2145e3af6a9e1065157561c6c94b46bd8531 100644 (file)
@@ -1,7 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2002 Tor Lillqvist
- * Copyright (C) 2007 Cody Russell
+ * Copyright (C) 2007-2008 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1266,6 +1266,19 @@ apply_filters (GdkWindow  *window,
   return result;
 }
 
+/*
+ * On Windows, transient windows will not have their own taskbar entries.
+ * Because of this, we must hide and restore groups of transients in both
+ * directions.  That is, all transient children must be hidden or restored
+ * with this window, but if this window's transient owner also has a
+ * transient owner then this window's transient owner must be hidden/restored
+ * with this one.  And etc, up the chain until we hit an ancestor that has no
+ * transient owner.
+ *
+ * It would be a good idea if applications don't chain transient windows
+ * together.  There's a limit to how much evil GTK can try to shield you
+ * from.
+ */
 static void
 show_window_recurse (GdkWindow *window, gboolean hide_window)
 {
@@ -1300,6 +1313,32 @@ show_window_recurse (GdkWindow *window, gboolean hide_window)
     }
 }
 
+static void
+show_window_internal (GdkWindow *window, gboolean hide_window)
+{
+  GdkWindow *tmp_window = NULL;
+  GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+  if (!tmp_impl->changing_state)
+    {
+      /* Find the top-level window in our transient chain. */
+      while (tmp_impl->transient_owner != NULL)
+       {
+         tmp_window = tmp_impl->transient_owner;
+         tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
+       }
+
+      /* If we couldn't find one, use the window provided. */
+      if (tmp_window == NULL)
+       {
+         tmp_window = window;
+       }
+
+      /* Recursively show/hide every window in the chain. */
+      show_window_recurse (tmp_window, hide_window);
+    }
+}
+
 static gboolean
 gdk_window_is_ancestor (GdkWindow *ancestor,
                        GdkWindow *window)
@@ -2875,6 +2914,14 @@ gdk_event_translate (MSG  *msg,
       return_val = TRUE;
       break;
 
+    case WM_SYSCOMMAND:
+
+      if (msg->wParam == SC_MINIMIZE || msg->wParam == SC_RESTORE)
+       {
+         show_window_internal (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
+       }
+      break;
+
     case WM_SIZE:
       GDK_NOTE (EVENTS,
                g_print (" %s %dx%d",
@@ -2898,6 +2945,7 @@ gdk_event_translate (MSG  *msg,
          gdk_synthesize_window_state (window,
                                       GDK_WINDOW_STATE_WITHDRAWN,
                                       GDK_WINDOW_STATE_ICONIFIED);
+         show_window_internal (window, TRUE);
        }
       else if ((msg->wParam == SIZE_RESTORED ||
                msg->wParam == SIZE_MAXIMIZED) &&
@@ -2910,11 +2958,14 @@ gdk_event_translate (MSG  *msg,
            handle_configure_event (msg, window);
          
          if (msg->wParam == SIZE_RESTORED)
-           gdk_synthesize_window_state (window,
-                                        GDK_WINDOW_STATE_ICONIFIED |
-                                        GDK_WINDOW_STATE_MAXIMIZED |
-                                        withdrawn_bit,
-                                        0);
+           {
+             gdk_synthesize_window_state (window,
+                                          GDK_WINDOW_STATE_ICONIFIED |
+                                          GDK_WINDOW_STATE_MAXIMIZED |
+                                          withdrawn_bit,
+                                          0);
+             show_window_internal (window, FALSE);
+           }
          else if (msg->wParam == SIZE_MAXIMIZED)
            gdk_synthesize_window_state (window,
                                         GDK_WINDOW_STATE_ICONIFIED |
@@ -3366,46 +3417,7 @@ gdk_event_translate (MSG  *msg,
        }
       break;
 
-    case WM_ACTIVATE: {
-      /*
-       * On Windows, transient windows will not have their own taskbar entries.
-       * Because of this, we must hide and restore groups of transients in both
-       * directions.  That is, all transient children must be hidden or restored
-       * with this window, but if this window's transient owner also has a
-       * transient owner then this window's transient owner must be hidden/restored
-       * with this one.  And etc, up the chain until we hit an ancestor that has no
-       * transient owner.
-       *
-       * It would be a good idea if applications don't chain transient windows
-       * together.  There's a limit to how much evil GTK can try to shield you
-       * from.
-       */
-      GdkWindow *tmp_window = NULL;
-      GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
-
-      while (tmp_impl->transient_owner != NULL)
-       {
-         tmp_window = tmp_impl->transient_owner;
-         tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
-       }
-
-      if (tmp_window == NULL)
-       tmp_window = window;
-
-      if (LOWORD (msg->wParam) == WA_INACTIVE && HIWORD (msg->wParam))
-        {
-         if (!tmp_impl->changing_state)
-           {
-             show_window_recurse (tmp_window, TRUE);
-           }
-        }
-      else if (LOWORD (msg->wParam) == WA_ACTIVE && HIWORD (msg->wParam))
-       {
-         if (!tmp_impl->changing_state)
-           {
-             show_window_recurse (tmp_window, FALSE);
-           }
-        }
+    case WM_ACTIVATE:
 
       /* Bring any tablet contexts to the top of the overlap order when
        * one of our windows is activated.
@@ -3415,7 +3427,7 @@ gdk_event_translate (MSG  *msg,
       if (LOWORD(msg->wParam) != WA_INACTIVE)
        _gdk_input_set_tablet_active ();
       break;
-    }
+
 
       /* Handle WINTAB events here, as we know that gdkinput.c will
        * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the